package com.geping.etl.common.service.impl;

import com.geping.etl.common.dto.*;
import com.geping.etl.common.entity.Sys_Auth_Role;
import com.geping.etl.common.entity.Sys_Auth_Role_User;
import com.geping.etl.common.entity.Sys_Department;
import com.geping.etl.common.entity.Sys_User;
import com.geping.etl.common.exceptoin.BusinessException;
import com.geping.etl.common.exceptoin.SystemCode;
import com.geping.etl.common.repository.*;
import com.geping.etl.common.service.SynBxSysUsersService;
import com.geping.etl.common.util.Constants;
import com.geping.etl.common.vo.BxResponseVo;
import com.geping.etl.utils.DateUtil;
import com.geping.etl.utils.EnvUitl;
import com.geping.etl.utils.base64.SecretUtil;
import com.geping.etl.utils.sm3.SM3PrintUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.swing.text.html.parser.Entity;
import java.util.*;


@Service
@Slf4j
public class SynBxSysUsersServiceImpl implements SynBxSysUsersService {

    @Autowired
    private Sys_UserRepository sysUserRepository;

    @Autowired
    private Sys_OrgRepository sysOrgRepository;

    @Autowired
    private Sys_Auth_RoleRepository sys_auth_roleRepository;

    @Autowired
    private Sys_Auth_Role_UserRepository sys_auth_role_userRepository;

    @Autowired
    private Sys_DepartmentRepository sysDepartmentRepository;

    @Override
    @Transactional
    public BxResponseVo createAccount(BxSysUserDto bxSysUserDto) {
        BxResponseVo bxResponseVo = new BxResponseVo();
        try {
            String errorMessage = checkNotBlank(bxSysUserDto);
            if(StringUtils.isNotBlank(errorMessage)){
                bxResponseVo.setReturnFlag("false");
                bxResponseVo.setReturnMessage(errorMessage);
                return bxResponseVo;
            }

            bxCommonCheck(bxSysUserDto.getAppKey(), bxSysUserDto.getAppPassword());
            //防并发重复
            synchronized(bxSysUserDto.getUid()) {
                //判断uid账号信息是否存在
                Sys_User sysUser = sysUserRepository.getOneByLoginId(bxSysUserDto.getUid());
                if(sysUser != null){
                    throw new BusinessException(SystemCode.BEIXIAN_USER_ALREADY_CREATE);
                }

                //分装用户信息（组织机构代码从sys_org查出，不会存在多条的情况）
                sysUser = buildCreateSysUser(bxSysUserDto);
                //判断部门信息
                Sys_Department sysDepartment = sysDepartmentRepository.getSys_DepartmentByDepartmentId(bxSysUserDto.getDepartmentCode());
                if(sysDepartment == null){
                    sysDepartment = new Sys_Department();
                    sysDepartment.setDepartmentName(bxSysUserDto.getDepartment());
                    sysDepartment.setDepartmentId(bxSysUserDto.getDepartmentCode());
                    //保存部门信息
                    sysDepartmentRepository.save(sysDepartment);
                }


                //有且仅有一条
                String orgId = sysOrgRepository.findAllSysOrg().get(0).getOrgId();
                if(StringUtils.isBlank(orgId)){
                    throw new BusinessException(SystemCode.BEIXIAN_ORG_CODE_NOE_CREATE);
                }
                sysUser.setOrgId(orgId);
                //保存用户信息
                sysUserRepository.save(sysUser);
            }
            //根据结果返回BxResponseVo封装对应
        }catch (BusinessException e){
            log.error("createAccount businessException, e = {}", e);
            bxResponseVo.setReturnFlag("false");
            bxResponseVo.setReturnMessage(e.getMessage());
        }catch (Exception e){
            log.error("createAccount exception, e = {}", e);
            bxResponseVo.setReturnFlag("false");
            bxResponseVo.setReturnMessage("系统异常，请联系管理员");
        }
        return bxResponseVo;
    }

    private String checkNotBlank(BxSysUserDto bxSysUserDto) {
        String message = "";
        if(StringUtils.isBlank(bxSysUserDto.getAppKey())){
            message = message + "业务系统的appKey不能为空；";
        }
        if(StringUtils.isBlank(bxSysUserDto.getAppPassword())){
            message = message + "业务系统的appPassword不能为空；";
        }
        if(StringUtils.isBlank(bxSysUserDto.getUid())){
            message = message + "登录账户名不能为空；";
        }
        if(StringUtils.isBlank(bxSysUserDto.getPassword())){
            message = message + "登录密码不能为空；";
        }
        if(StringUtils.isBlank(bxSysUserDto.getDepartment())){
            message = message + "所在组织节点名称不能为空；";
        }
        if(StringUtils.isBlank(bxSysUserDto.getDepartmentCode())){
            message = message + "所在组织节点编码不能为空；";
        }
        return message;
    }

    @Override
    public BxResponseVo deleteAccount(BxDeleteUserDto bxDeleteUserDto){
        BxResponseVo bxResponseVo = new BxResponseVo();
        try {
            String errorMessage = checkNotBlank(bxDeleteUserDto);
            if(StringUtils.isNotBlank(errorMessage)){
                bxResponseVo.setReturnFlag("false");
                bxResponseVo.setReturnMessage(errorMessage);
                return bxResponseVo;
            }


            bxCommonCheck(bxDeleteUserDto.getAppKey(), bxDeleteUserDto.getAppPassword());

            //判断uid账号信息是否存在
            Sys_User sysUser = sysUserRepository.getOneByLoginId(bxDeleteUserDto.getUid());
            if(sysUser == null){
                throw new BusinessException(SystemCode.BEIXIAN_USER_NOT_CREATE);
            }

            //根据uid将账号信息逻辑删除
            sysUser.setIsDelete("Y");
            sysUserRepository.save(sysUser);

            //根据结果返回BxResponseVo封装对应
        }catch (BusinessException e){
            log.error("deleteAccount businessException, e = {}", e);
            bxResponseVo.setReturnFlag("false");
            bxResponseVo.setReturnMessage(e.getMessage());
        }catch (Exception e){
            log.error("deleteAccount exception, e = {}", e);
            bxResponseVo.setReturnFlag("false");
            bxResponseVo.setReturnMessage("系统异常，请联系管理员");
        }
        return bxResponseVo;

    }

    private String checkNotBlank(BxDeleteUserDto bxDeleteUserDto) {
        String message = "";
        if(StringUtils.isBlank(bxDeleteUserDto.getAppKey())){
            message = message + "业务系统的appKey不能为空；";
        }
        if(StringUtils.isBlank(bxDeleteUserDto.getAppPassword())){
            message = message + "业务系统的appPassword不能为空；";
        }
        if(StringUtils.isBlank(bxDeleteUserDto.getUid())){
            message = message + "登录账户名不能为空；";
        }
        return message;
    }

    @Override
    @Transactional
    public BxResponseVo updateAccount(BxSysUserUpdateDto bxSysUserUpdateDto) {
        BxResponseVo bxResponseVo = new BxResponseVo();
        try {

            String errorMessage = checkNotBlank(bxSysUserUpdateDto);
            if(StringUtils.isNotBlank(errorMessage)){
                bxResponseVo.setReturnFlag("false");
                bxResponseVo.setReturnMessage(errorMessage);
                return bxResponseVo;
            }

            bxCommonCheck(bxSysUserUpdateDto.getAppKey(), bxSysUserUpdateDto.getAppPassword());

            //判断uid账号信息是否存在
            Sys_User sysUser = sysUserRepository.getOneByLoginId(bxSysUserUpdateDto.getUid());
            if (sysUser == null) {
                throw new BusinessException(SystemCode.BEIXIAN_USER_NOT_CREATE);
            }
            //判断部门信息
            if(StringUtils.isNotBlank(bxSysUserUpdateDto.getDepartmentCode())){

                //判断部门信息
                Sys_Department sysDepartment = sysDepartmentRepository.getSys_DepartmentByDepartmentId(bxSysUserUpdateDto.getDepartmentCode());
                if(sysDepartment == null){
                    throw new BusinessException(SystemCode.BEIXIAN_DEPARTMENT_NOE_CREATE);
                }
                if(StringUtils.isNotBlank(bxSysUserUpdateDto.getDepartment())) {
                    sysDepartment.setDepartmentName(bxSysUserUpdateDto.getDepartment());
                    sysDepartmentRepository.save(sysDepartment);
                }

            }

            //分装用户信息
            sysUser = rebuildCreateSysUser(bxSysUserUpdateDto, sysUser);

            //根据uid修改用户信息
            sysUserRepository.save(sysUser);

            //返回BxResponseVo封装对应
        }catch (BusinessException e){
            log.error("updateAccount businessException, e = {}", e);
            bxResponseVo.setReturnFlag("false");
            bxResponseVo.setReturnMessage(e.getMessage());
        }catch (Exception e){
            log.error("updateAccount exception, e = {}", e);
            bxResponseVo.setReturnFlag("false");
            bxResponseVo.setReturnMessage("系统异常，请联系管理员");
        }
        return bxResponseVo;

    }

    private String checkNotBlank(BxSysUserUpdateDto bxSysUserUpdateDto) {

        String message = "";
        if(StringUtils.isBlank(bxSysUserUpdateDto.getAppKey())){
            message = message + "业务系统的appKey不能为空；";
        }
        if(StringUtils.isBlank(bxSysUserUpdateDto.getAppPassword())){
            message = message + "业务系统的appPassword不能为空；";
        }
        if(StringUtils.isBlank(bxSysUserUpdateDto.getUid())){
            message = message + "登录账户名不能为空；";
        }
        return message;
    }

    @Override
    public BxResponseVo changePassword(BxPasswordUpdateUserDto bxPasswordUpdateUserDto) {
        BxResponseVo bxResponseVo = new BxResponseVo();
        try {

            String errorMessage = checkNotBlank(bxPasswordUpdateUserDto);
            if(StringUtils.isNotBlank(errorMessage)){
                bxResponseVo.setReturnFlag("false");
                bxResponseVo.setReturnMessage(errorMessage);
                return bxResponseVo;
            }

            bxCommonCheck(bxPasswordUpdateUserDto.getAppKey(), bxPasswordUpdateUserDto.getAppPassword());

            //判断uid账号信息是否存在
            Sys_User sysUser = sysUserRepository.getOneByLoginId(bxPasswordUpdateUserDto.getUid());
            if (sysUser == null) {
                throw new BusinessException(SystemCode.BEIXIAN_USER_NOT_CREATE);
            }

            //根据uid变更用户密码信息
            sysUser.setPassword(SM3PrintUtil.getSM3Str(SecretUtil.decoder(bxPasswordUpdateUserDto.getPassword())));
            sysUser.setLastModifyDate(DateUtil.getTime());
            sysUserRepository.save(sysUser);

            //返回BxResponseVo封装对应
        }catch (BusinessException e){
            log.error("changePassword businessException, e = {}", e);
            bxResponseVo.setReturnFlag("false");
            bxResponseVo.setReturnMessage(e.getMessage());
        }catch (Exception e){
            log.error("changePassword exception, e = {}", e);
            bxResponseVo.setReturnFlag("false");
            bxResponseVo.setReturnMessage("系统异常，请联系管理员");
        }
        return bxResponseVo;
    }

    private String checkNotBlank(BxPasswordUpdateUserDto bxPasswordUpdateUserDto) {
        String message = "";
        if(StringUtils.isBlank(bxPasswordUpdateUserDto.getAppKey())){
            message = message + "业务系统的appKey不能为空；";
        }
        if(StringUtils.isBlank(bxPasswordUpdateUserDto.getAppPassword())){
            message = message + "业务系统的appPassword不能为空；";
        }
        if(StringUtils.isBlank(bxPasswordUpdateUserDto.getUid())){
            message = message + "登录账户名不能为空；";
        }
        if(StringUtils.isBlank(bxPasswordUpdateUserDto.getPassword())){
            message = message + "账户密码不能为空；";
        }
        return message;
    }

    @Override
    public BxResponseVo enableAccount(BxEnableUserDto bxEnableUserDto) {
        BxResponseVo bxResponseVo = new BxResponseVo();
        try {

            String errorMessage = checkNotBlank(bxEnableUserDto);
            if(StringUtils.isNotBlank(errorMessage)){
                bxResponseVo.setReturnFlag("false");
                bxResponseVo.setReturnMessage(errorMessage);
                return bxResponseVo;
            }

            bxCommonCheck(bxEnableUserDto.getAppKey(), bxEnableUserDto.getAppPassword());

            //判断uid账号信息是否存在
            Sys_User sysUser = sysUserRepository.getOneByLoginId(bxEnableUserDto.getUid());
            if (sysUser == null) {
                throw new BusinessException(SystemCode.BEIXIAN_USER_NOT_CREATE);
            }

            //根据uid将用户锁定状态改为未锁定
            sysUser.setIsLocked("N");
            sysUserRepository.save(sysUser);

            //返回BxResponseVo封装对应
        }catch (BusinessException e){
            log.error("changePassword businessException, e = {}", e);
            bxResponseVo.setReturnFlag("false");
            bxResponseVo.setReturnMessage(e.getMessage());
        }catch (Exception e){
            log.error("changePassword exception, e = {}", e);
            bxResponseVo.setReturnFlag("false");
            bxResponseVo.setReturnMessage("系统异常，请联系管理员");
        }
        return bxResponseVo;
    }

    private String checkNotBlank(BxEnableUserDto bxEnableUserDto) {
        String message = "";
        if(StringUtils.isBlank(bxEnableUserDto.getAppKey())){
            message = message + "业务系统的appKey不能为空；";
        }
        if(StringUtils.isBlank(bxEnableUserDto.getAppPassword())){
            message = message + "业务系统的appPassword不能为空；";
        }
        if(StringUtils.isBlank(bxEnableUserDto.getUid())){
            message = message + "登录账户名不能为空；";
        }
        return message;
    }

    @Override
    public BxResponseVo disableAccount(BxDisableUserDto bxDisableUserDto) {

        BxResponseVo bxResponseVo = new BxResponseVo();
        try {

            String errorMessage = checkNotBlank(bxDisableUserDto);
            if(StringUtils.isNotBlank(errorMessage)){
                bxResponseVo.setReturnFlag("false");
                bxResponseVo.setReturnMessage(errorMessage);
                return bxResponseVo;
            }

            bxCommonCheck(bxDisableUserDto.getAppKey(), bxDisableUserDto.getAppPassword());

            //判断uid账号信息是否存在
            Sys_User sysUser = sysUserRepository.getOneByLoginId(bxDisableUserDto.getUid());
            if (sysUser == null) {
                throw new BusinessException(SystemCode.BEIXIAN_USER_NOT_CREATE);
            }

            //根据uid将用户锁定状态改为已锁定
            sysUser.setIsLocked("Y");
            sysUserRepository.save(sysUser);

            //返回BxResponseVo封装对应
        }catch (BusinessException e){
            log.error("disableAccount businessException, e = {}", e);
            bxResponseVo.setReturnFlag("false");
            bxResponseVo.setReturnMessage(e.getMessage());
        }catch (Exception e){
            log.error("disableAccount exception, e = {}", e);
            bxResponseVo.setReturnFlag("false");
            bxResponseVo.setReturnMessage("系统异常，请联系管理员");
        }
        return bxResponseVo;
    }

    private String checkNotBlank(BxDisableUserDto bxDisableUserDto) {
        String message = "";
        if(StringUtils.isBlank(bxDisableUserDto.getAppKey())){
            message = message + "业务系统的appKey不能为空；";
        }
        if(StringUtils.isBlank(bxDisableUserDto.getAppPassword())){
            message = message + "业务系统的appPassword不能为空；";
        }
        if(StringUtils.isBlank(bxDisableUserDto.getUid())){
            message = message + "登录账户名不能为空；";
        }
        return message;
    }

    @Override
    public BxResponseVo updateRole(BxUpdateRoleDto bxUpdateRoleDto) {
        BxResponseVo bxResponseVo = new BxResponseVo();
        try {
            String errorMessage = checkNotBlank(bxUpdateRoleDto);
            if (StringUtils.isNotBlank(errorMessage)) {
                bxResponseVo.setReturnFlag("false");
                bxResponseVo.setReturnMessage(errorMessage);
                return bxResponseVo;
            }

            bxCommonCheck(bxUpdateRoleDto.getAppKey(), bxUpdateRoleDto.getAppPassword());

            //判断uid账号信息是否存在
            Sys_User sysUser = sysUserRepository.getOneByLoginId(bxUpdateRoleDto.getUid());
            if (sysUser == null){
                throw new BusinessException(SystemCode.BEIXIAN_USER_NOT_CREATE);
            }

            //判断传来的角色是否都存在
            HashMap<String, String> roleMap = bxUpdateRoleDto.getAppRole();
            Set<String> idSet = roleMap.keySet();
            for (String idStr : idSet) {
                String roleName = roleMap.get(idStr);
                Integer id = Integer.valueOf(idStr);
                Sys_Auth_Role role = sys_auth_roleRepository.getRoleById(id, roleName);
                if (role == null){
                    throw new BusinessException(SystemCode.BEIXIAN_ROLE_NOT_CREATE);
                }
            }

            //根据用户id 和 角色id进行角色分配  先删除后添加
            sys_auth_role_userRepository.deleteSysAuthRoleUser(String.valueOf(sysUser.getId()));
            List<Sys_Auth_Role_User> role_users = new ArrayList<>();
            for (String id : idSet) {
                Sys_Auth_Role_User role_user = new Sys_Auth_Role_User();
                role_user.setRoleId(id);
                role_user.setUserId(String.valueOf(sysUser.getId()));
                role_users.add(role_user);
            }
            sys_auth_role_userRepository.save(role_users);

        }catch (BusinessException e){
            log.error("updateRole businessException, e = {}",e);
            bxResponseVo.setReturnFlag("false");
            bxResponseVo.setReturnMessage(e.getMessage());
        }catch (NumberFormatException e){
            log.error("updateRole NumberFormatException, e = {}",e);
            bxResponseVo.setReturnFlag("false");
            bxResponseVo.setReturnMessage("角色id存在非字符串形式的数字");
        }catch (Exception e){
            log.error("updateRole exception, e = {}",e);
            bxResponseVo.setReturnFlag("false");
            bxResponseVo.setReturnMessage("系统异常，请联系管理员");
        }
        return bxResponseVo;
    }

    private String checkNotBlank(BxUpdateRoleDto bxUpdateRoleDto) {
        StringBuffer message = new StringBuffer();
        if (StringUtils.isBlank(bxUpdateRoleDto.getAppKey())) {
            message.append("业务系统的appKey不能为空；");
        }
        if (StringUtils.isBlank(bxUpdateRoleDto.getAppPassword())) {
            message.append("业务系统的appPassword不能为空；");
        }
        if (StringUtils.isBlank(bxUpdateRoleDto.getUserType())) {
            message.append("用户类型不能为空；");
        }
        if (StringUtils.isBlank(bxUpdateRoleDto.getUid())) {
            message.append("应用帐号不能为空；");
        }
        if (StringUtils.isBlank(bxUpdateRoleDto.getName())) {
            message.append("应用帐号名称不能为空；");
        }
        if (bxUpdateRoleDto.getAppRole()==null) {
            message.append("权限编码和权限名称键值对不能为空；");
        }
        return String.valueOf(message);
    }

    private Sys_User buildCreateSysUser(BxSysUserDto bxSysUserDto) {
        Sys_User sysUser = new Sys_User();
        sysUser.setLoginId(bxSysUserDto.getUid());
        sysUser.setPassword(SM3PrintUtil.getSM3Str(SecretUtil.decoder(bxSysUserDto.getPassword())));
        sysUser.setIsLocked("1".equals(bxSysUserDto.getStatus())?"Y":"N");
        sysUser.setUserEname(bxSysUserDto.getSpellName());
        sysUser.setUserCname(bxSysUserDto.getName());
        sysUser.setAddress(bxSysUserDto.getOfficeaddress());
        sysUser.setEmail(bxSysUserDto.getEmail());
        sysUser.setMobile(bxSysUserDto.getMobile());
        sysUser.setDescription(bxSysUserDto.getDescription());
        sysUser.setHandleperson("单点登录中心");
        sysUser.setHandledate(DateUtil.getTime());
        sysUser.setCreateTime(DateUtil.getTime());
        sysUser.setDepartId(bxSysUserDto.getDepartmentCode());
        sysUser.setIp("192.168.1.110");
        sysUser.setIsDept("N");
        sysUser.setFailNums("0");
        return sysUser;
    }

    private Sys_User rebuildCreateSysUser(BxSysUserUpdateDto bxSysUserUpdateDto, Sys_User sysUser) {
        sysUser.setIsLocked("1".equals(bxSysUserUpdateDto.getStatus())?"Y":"N");
        sysUser.setUserEname(bxSysUserUpdateDto.getSpellName());
        sysUser.setUserCname(bxSysUserUpdateDto.getName());
        sysUser.setAddress(bxSysUserUpdateDto.getOfficeaddress());
        sysUser.setEmail(bxSysUserUpdateDto.getEmail());
        sysUser.setMobile(bxSysUserUpdateDto.getMobile());
        sysUser.setDescription(bxSysUserUpdateDto.getDescription());
        sysUser.setHandleperson("单点登录中心");
        sysUser.setHandlename("系统同步修改");
        sysUser.setHandledate(DateUtil.getTime());
        sysUser.setDepartId(bxSysUserUpdateDto.getDepartmentCode());
        return sysUser;
    }

    private void bxCommonCheck(String appKey, String appPassword) {
        //判断北现同步开关是否开启
        if (!Constants.BX_SYN_USER_ON.equals(EnvUitl.props.getProperty("beixian.user"))) {
            throw new BusinessException(SystemCode.BEIXIAN_SYN_OFF);
        }
        //判断appKey和appPassword是否正确
        if(!appKey.equals(EnvUitl.props.getProperty("beixian.appKey"))
                || !SecretUtil.decoder(appPassword).equals(EnvUitl.props.getProperty("beixian.appPassword"))){
            throw new BusinessException(SystemCode.BEIXIAN_APP_AUTH_FAIL);
        }
    }


}
